{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获得前n个主成分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X = np.empty((100, 2))\n",
    "X[:,0] = np.random.uniform(0., 100., size=100)\n",
    "X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def demean(X):\n",
    "    return X - np.mean(X, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X = demean(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n73eXV+7Yc1g3XjWZ+zy/XXjt1M/Hji9EkzaJJeWE4phpi5FVUaWzdvrhzO3vTNLRmeuDnquo3oFs\nafEmmOdmkne2ah2VUf2u68arJrXv2fm+bUm1iitFzLRF6aqozEhpOeIi1T950iZ1VUZllV1ec9mE\ndu2f69uWlKu4moyUDqKW0uqIRXLdedImdVZGbd0wqcenN+nozPV6fHqT9j07v2xbymxrDLOSU0XA\nR9RSWo647HX2Yxo8HdSWstratC0Oq0ZKB9FLZVJPkfLKPLNVY0pvDWpLWW2NZVZyqujhA4GEqP7p\nTpv0/l5M6a1Bbem3efn/vXKiUCompqecFNHDBwIq82kkpjVrBrWl9/2V543pN789oWPHFySNPogb\n01NOiijLBFC6UJukFCl9bbJoyjLN7DpJ/yxphaQvuvtM2edEfKjJbrdQqZiYnnJSVGrAN7MVkj4v\n6e2Snpf0XTPb7e5Pl3lexIWabIRMxaQyiB+jsgdtr5Z0xN1/6O6vSrpX0paSz4nIpLyyZqxSq0WP\nacC5zcpO6UxK+knX6+cl/Xn3B8zsVkm3StKll15acnNQByorwkrxiYlUTBxqr9Jx952SdkqLg7Y1\nNwcloLIirFRr0UnF1K/slM6cpNVdr1d1jqFFeJwPiycmjKrsgP9dSevMbK2Z/Y6kmyXtLvmciExK\nyyOkgOWKMapSUzrufsLMPippjxbLMr/k7ofKPCfixON8OHXukEV5bdpKz+G7+9clfb3s8wDDSjV4\n1TUAmuJgMc5U+6AtUIXe4D5oPffY1fHElOpgMU4j4KOxloL83LHjMunUzllzx47rnieeO2snrdSC\nV9YTilRez5/B4vQR8NFIvemH3uDer/43leCVlV7Z9tWDkkkLJ/3UsZBPLZTXpo/lkdFIWemHPFIJ\nXlnXt/Canwr2S0LOaKa8Nn308NFIeXrq3WkeKa3gNcyTSKinFmbLpo+AjygVraDpl35YMj62Qjde\nNal9z84nGbwGXV/vZ0OhvDZtBHyUbtjgHaL8L6tWfalHP5lYcM+SdX1j59gZOXwpracWlI+Aj1KN\nErxDlP81Pf3Q7/qyjjXlmlEcO16hVKPsdLR2+uHMKhqTdHTm+rANBBog745XVOmgVKPUbrNWDFAO\nAj5KNUrwpvwPKAcBPxGp7XC0ZJTgzeqaQDkYtE1AyotWjTp4Okr5X6qLoQFVoYefgNT3hN26YVLb\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10c9fc3c8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:,0], X[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def f(w, X):\n",
    "    return np.sum((X.dot(w)**2)) / len(X)\n",
    "\n",
    "def df(w, X):\n",
    "    return X.T.dot(X.dot(w)) * 2. / len(X)\n",
    "\n",
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "def first_component(X, initial_w, eta, n_iters = 1e4, epsilon=1e-8):\n",
    "    \n",
    "    w = direction(initial_w) \n",
    "    cur_iter = 0\n",
    "\n",
    "    while cur_iter < n_iters:\n",
    "        gradient = df(w, X)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w) \n",
    "        if(abs(f(w, X) - f(last_w, X)) < epsilon):\n",
    "            break\n",
    "            \n",
    "        cur_iter += 1\n",
    "\n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.78307181,  0.62193129])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initial_w = np.random.random(X.shape[1])\n",
    "eta = 0.01\n",
    "w = first_component(X, initial_w, eta)\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X2 = np.empty(X.shape)\n",
    "for i in range(len(X)):\n",
    "    X2[i] = X[i] - X[i].dot(w) * w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10cdbbf60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2[:,0], X2[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X2 = X - X.dot(w).reshape(-1, 1) * w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10cd441d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2[:,0], X2[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.6219279 ,  0.78307451])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w2 = first_component(X2, initial_w, eta)\n",
    "w2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.3300901158005445e-06"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w.dot(w2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def first_n_components(n, X, eta=0.01, n_iters = 1e4, epsilon=1e-8):\n",
    "    X_pca = X.copy()\n",
    "    X_pca = demean(X_pca)\n",
    "    res = []\n",
    "    for i in range(n):\n",
    "        initial_w = np.random.random(X_pca.shape[1])\n",
    "        w = first_component(X_pca, initial_w, eta)\n",
    "        res.append(w)\n",
    "        \n",
    "        X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w\n",
    "        \n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([ 0.78307192,  0.62193116]), array([-0.62192683,  0.78307536])]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "first_n_components(2, X)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
